﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

using DigitalQuran.Extensions;

namespace DigitalQuran.Statistic
{
    /// <summary>
    /// Statistics Engine responsible for statistics of letter and word
    /// </summary>
    public sealed class StatisticalEngine
    {
        /// <summary>
        /// Create new instance of statistical engine
        /// </summary>
        public StatisticalEngine()
        {
            LetterStatistic = new LetterStatisticTable();
            PhraseLetterStatistics = new LetterStatisticTable();
        }

        /// <summary>
        /// Gets the Letter Statistics Table
        /// </summary>
        public LetterStatisticTable LetterStatistic { get; private set; }

        /// <summary>
        /// Gets Phrase Letter Statistics Table
        /// </summary>
        public LetterStatisticTable PhraseLetterStatistics { get; private set; }

        /// <summary>
        /// Calculate Statistics of letter
        /// </summary>
        /// <param name="text">Source string used whose letter statistics to calculate</param>
        /// <returns>Returns table holding statistics information</returns>
        public LetterStatisticTable CalculateLetterStatistics(string text)
        {
            if (LetterStatistic.Text.Length == text.Length && LetterStatistic.Text == text)
                return LetterStatistic;

            LetterStatistic.Clear();
            LetterStatistic.Text = text;

            if (String.IsNullOrEmpty(text)) return LetterStatistic;

            text = text.Replace("\r", "").Replace("\n", "").Replace(" ", "");

            for (int i = 0; i < text.Length; i++)
            {
                // ignore digits, stop markers & brackets
                if (Constants.ArabicDigits.Contains(text[i]) ||
                    Constants.StopMarkers.Contains(text[i]) ||
                    text[i] == '{' ||
                    text[i] == '}') continue;

                LetterStatistic.AddOrUpdate(text[i]);
                LetterStatistic.FrequencyCount++;
            }

            return LetterStatistic;
        }

        /// <summary>
        /// Calculate Letter Statistics
        /// </summary>
        /// <param name="qObject">Quran Object whose letters statictics to calculate</param>
        /// <returns>Returns table holding statistics information</returns>
        public LetterStatisticTable CalculateLetterStatistics(IQuranObject qObject, string textMode) {

            return CalculateLetterStatistics(qObject.ToString(textMode));
        }

        public LetterStatisticTable CalculatePhraseLetterStatistics(string text, string phrase, FindByFrequencySumType sumType)
        {
            if (String.IsNullOrEmpty(text)|| String.IsNullOrEmpty(phrase)) return PhraseLetterStatistics;            

            if (sumType == FindByFrequencySumType.NoDuplicateLetters)
                phrase = phrase.RemoveDuplicates();

            phrase = phrase.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            
            PhraseLetterStatistics.Clear();

            for (int i = 0; i < phrase.Length; i++)
            {
                int frequency = 0;
                for (int j = 0; j < text.Length; j++)
                {
                    if (Constants.ArabicDigits.Contains(text[j]) ||
                        Constants.StopMarkers.Contains(text[j]) ||
                        text[j] == '{' ||
                        text[j] == '}') continue;

                    if (phrase[i] == text[j])                                            
                        frequency++;                    
                }

                if (frequency > 0)
                {
                    PhraseLetterStatistics.FrequencyCount += frequency;

                    PhraseLetterStatistics.Add(new LetterStatistic
                    {
                        Order = PhraseLetterStatistics.Count + 1,
                        Letter = phrase[i],
                        Frequency = frequency
                    });                    
                }
            }

            return PhraseLetterStatistics;
        }
    }
}